"""动态模型模板管理API端点。"""

from fastapi import APIRouter, Depends, HTTPException, status
from typing import List, Dict, Any, Optional
from datetime import datetime
from pydantic import BaseModel, Field
import uuid
import logging
from motor.motor_asyncio import AsyncIOMotorDatabase

from ..core.auth import get_current_user
from ..core.database import get_db

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/v1/model-templates", tags=["model-templates"])


class ModelTemplate(BaseModel):
    """模型模板数据结构。"""
    
    id: Optional[str] = None
    name: str = Field(..., min_length=1, max_length=100)
    provider: str = Field(..., min_length=1, max_length=50)
    category: str = Field(default="general", pattern="^(general|chat|completion|embedding|vision|audio)$")
    model_name: str = Field(..., min_length=1)
    base_url: str = Field(..., pattern="^https?://")
    
    # 默认配置
    default_config: Dict[str, Any] = Field(default_factory=dict)
    
    # 能力描述
    capabilities: Dict[str, Any] = Field(default_factory=dict)
    
    # 元数据
    description: Optional[str] = None
    icon_url: Optional[str] = None
    documentation_url: Optional[str] = None
    example_api_key_format: Optional[str] = None
    
    # 版本和状态
    version: str = Field(default="1.0")
    status: str = Field(default="active", pattern="^(active|deprecated|beta|experimental)$")
    is_official: bool = Field(default=False, description="是否为官方模板")
    is_verified: bool = Field(default=False, description="是否已验证")
    
    # 时间戳
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    created_by: Optional[str] = None
    
    # 标签
    tags: List[str] = Field(default_factory=list)
    
    # 使用统计
    usage_count: int = Field(default=0)
    rating: Optional[float] = Field(None, ge=0, le=5)
    
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat() if v else None
        }


class CreateTemplateRequest(BaseModel):
    """创建模板请求。"""
    
    name: str = Field(..., min_length=1, max_length=100)
    provider: str = Field(..., min_length=1, max_length=50)
    category: str = Field(default="general")
    model_name: str = Field(..., min_length=1)
    base_url: str = Field(..., pattern="^https?://")
    default_config: Dict[str, Any] = Field(default_factory=dict)
    capabilities: Dict[str, Any] = Field(default_factory=dict)
    description: Optional[str] = None
    icon_url: Optional[str] = None
    documentation_url: Optional[str] = None
    example_api_key_format: Optional[str] = None
    tags: List[str] = Field(default_factory=list)


class UpdateTemplateRequest(BaseModel):
    """更新模板请求。"""
    
    name: Optional[str] = Field(None, min_length=1, max_length=100)
    category: Optional[str] = None
    model_name: Optional[str] = Field(None, min_length=1)
    base_url: Optional[str] = Field(None, pattern="^https?://")
    default_config: Optional[Dict[str, Any]] = None
    capabilities: Optional[Dict[str, Any]] = None
    description: Optional[str] = None
    icon_url: Optional[str] = None
    documentation_url: Optional[str] = None
    example_api_key_format: Optional[str] = None
    status: Optional[str] = None
    tags: Optional[List[str]] = None


# 预定义的官方模板
OFFICIAL_TEMPLATES = [
    ModelTemplate(
        id="openai-gpt4",
        name="OpenAI GPT-4",
        provider="openai",
        category="chat",
        model_name="gpt-4",
        base_url="https://api.openai.com/v1",
        default_config={
            "temperature": 0.7,
            "max_tokens": 4096,
            "top_p": 1.0
        },
        capabilities={
            "max_tokens": 8192,
            "supports_streaming": True,
            "supports_function_calling": True,
            "supports_vision": True,
            "context_window": 128000
        },
        description="OpenAI最强大的模型，适合复杂任务",
        icon_url="https://openai.com/favicon.ico",
        documentation_url="https://platform.openai.com/docs/models/gpt-4",
        example_api_key_format="sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        is_official=True,
        is_verified=True,
        tags=["advanced", "multimodal", "reasoning"]
    ),
    ModelTemplate(
        id="openai-gpt35",
        name="OpenAI GPT-3.5 Turbo",
        provider="openai",
        category="chat",
        model_name="gpt-3.5-turbo",
        base_url="https://api.openai.com/v1",
        default_config={
            "temperature": 0.7,
            "max_tokens": 2048
        },
        capabilities={
            "max_tokens": 4096,
            "supports_streaming": True,
            "supports_function_calling": True,
            "context_window": 16384
        },
        description="快速高效的模型，适合大多数任务",
        icon_url="https://openai.com/favicon.ico",
        documentation_url="https://platform.openai.com/docs/models/gpt-3-5",
        example_api_key_format="sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        is_official=True,
        is_verified=True,
        tags=["fast", "efficient", "general"]
    ),
    ModelTemplate(
        id="anthropic-claude3",
        name="Anthropic Claude 3",
        provider="anthropic",
        category="chat",
        model_name="claude-3-opus-20240229",
        base_url="https://api.anthropic.com/v1",
        default_config={
            "temperature": 0.7,
            "max_tokens": 4096
        },
        capabilities={
            "max_tokens": 4096,
            "supports_streaming": True,
            "supports_vision": True,
            "context_window": 200000
        },
        description="Claude最强大的模型，擅长长文本处理",
        icon_url="https://anthropic.com/favicon.ico",
        documentation_url="https://docs.anthropic.com/claude/docs",
        example_api_key_format="sk-ant-api03-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        is_official=True,
        is_verified=True,
        tags=["long-context", "multimodal", "safe"]
    ),
    ModelTemplate(
        id="deepseek-chat",
        name="DeepSeek Chat",
        provider="deepseek",
        category="chat",
        model_name="deepseek-chat",
        base_url="https://api.deepseek.com/v1",
        default_config={
            "temperature": 0.7,
            "max_tokens": 4096
        },
        capabilities={
            "max_tokens": 4096,
            "supports_streaming": True,
            "supports_function_calling": True,
            "context_window": 32768
        },
        description="高效的中英双语模型",
        documentation_url="https://platform.deepseek.com/docs",
        example_api_key_format="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        is_official=True,
        is_verified=True,
        tags=["bilingual", "chinese", "cost-effective"]
    ),
    ModelTemplate(
        id="qwen-max",
        name="通义千问 Max",
        provider="alibaba",
        category="chat",
        model_name="qwen-max",
        base_url="https://dashscope.aliyuncs.com/api/v1",
        default_config={
            "temperature": 0.7,
            "max_tokens": 2048
        },
        capabilities={
            "max_tokens": 8192,
            "supports_streaming": True,
            "supports_function_calling": True,
            "context_window": 30720
        },
        description="阿里巴巴最强大的语言模型",
        documentation_url="https://help.aliyun.com/document_detail/2399482.html",
        example_api_key_format="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        is_official=True,
        is_verified=True,
        tags=["chinese", "commercial", "alibaba"]
    )
]


@router.get("", response_model=List[ModelTemplate])
async def get_all_templates(
    provider: Optional[str] = None,
    category: Optional[str] = None,
    status: Optional[str] = None,
    include_user_templates: bool = True,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> List[ModelTemplate]:
    """
    获取所有模型模板。
    
    Args:
        provider: 按提供商筛选
        category: 按类别筛选
        status: 按状态筛选
        include_user_templates: 是否包含用户自定义模板
    
    Returns:
        模板列表
    """
    try:
        templates = []
        
        # 添加官方模板
        for template in OFFICIAL_TEMPLATES:
            if provider and template.provider != provider:
                continue
            if category and template.category != category:
                continue
            if status and template.status != status:
                continue
            templates.append(template)
        
        # 添加用户自定义模板
        if include_user_templates:
            query = {"created_by": current_user["sub"]}
            if provider:
                query["provider"] = provider
            if category:
                query["category"] = category
            if status:
                query["status"] = status
            
            user_templates = await db.model_templates.find(query).to_list(None)
            for tmpl in user_templates:
                templates.append(ModelTemplate(**tmpl))
        
        # 按提供商分组排序
        templates.sort(key=lambda x: (x.provider, not x.is_official, x.name))
        
        return templates
        
    except Exception as e:
        logger.error(f"获取模板列表失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取模板列表失败"
        )


@router.get("/{template_id}", response_model=ModelTemplate)
async def get_template(
    template_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> ModelTemplate:
    """
    获取特定模板。
    
    Args:
        template_id: 模板ID
    
    Returns:
        模板详情
    """
    try:
        # 检查官方模板
        for template in OFFICIAL_TEMPLATES:
            if template.id == template_id:
                return template
        
        # 检查用户模板
        user_template = await db.model_templates.find_one({
            "id": template_id,
            "created_by": current_user["sub"]
        })
        
        if user_template:
            return ModelTemplate(**user_template)
        
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="模板未找到"
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取模板 {template_id} 失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取模板失败"
        )


@router.post("", response_model=ModelTemplate, status_code=status.HTTP_201_CREATED)
async def create_template(
    request: CreateTemplateRequest,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> ModelTemplate:
    """
    创建新的模型模板。
    
    Args:
        request: 模板创建请求
    
    Returns:
        创建的模板
    """
    try:
        # 检查名称是否重复
        existing = await db.model_templates.find_one({
            "name": request.name,
            "created_by": current_user["sub"]
        })
        
        if existing:
            raise HTTPException(
                status_code=status.HTTP_409_CONFLICT,
                detail=f"模板名称 '{request.name}' 已存在"
            )
        
        # 创建模板
        template_id = str(uuid.uuid4())
        now = datetime.utcnow()
        
        template_data = {
            "id": template_id,
            "created_by": current_user["sub"],
            "created_at": now,
            "updated_at": now,
            "version": "1.0",
            "status": "active",
            "is_official": False,
            "is_verified": False,
            "usage_count": 0,
            **request.dict()
        }
        
        # 存储到数据库
        await db.model_templates.insert_one(template_data)
        
        # 记录审计日志
        await db.audit_logs.insert_one({
            "user_id": current_user["sub"],
            "action": "create_model_template",
            "resource_id": template_id,
            "resource_type": "model_template",
            "details": {"name": request.name, "provider": request.provider},
            "timestamp": now
        })
        
        return ModelTemplate(**template_data)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"创建模板失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="创建模板失败"
        )


@router.put("/{template_id}", response_model=ModelTemplate)
async def update_template(
    template_id: str,
    request: UpdateTemplateRequest,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> ModelTemplate:
    """
    更新模型模板。
    
    Args:
        template_id: 模板ID
        request: 更新请求
    
    Returns:
        更新后的模板
    """
    try:
        # 检查是否为官方模板（不可修改）
        for template in OFFICIAL_TEMPLATES:
            if template.id == template_id:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail="不能修改官方模板"
                )
        
        # 检查用户模板
        existing = await db.model_templates.find_one({
            "id": template_id,
            "created_by": current_user["sub"]
        })
        
        if not existing:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="模板未找到"
            )
        
        # 检查名称是否重复
        if request.name and request.name != existing["name"]:
            duplicate = await db.model_templates.find_one({
                "name": request.name,
                "created_by": current_user["sub"],
                "id": {"$ne": template_id}
            })
            
            if duplicate:
                raise HTTPException(
                    status_code=status.HTTP_409_CONFLICT,
                    detail=f"模板名称 '{request.name}' 已存在"
                )
        
        # 更新模板
        update_data = {k: v for k, v in request.dict().items() if v is not None}
        update_data["updated_at"] = datetime.utcnow()
        
        await db.model_templates.update_one(
            {"id": template_id, "created_by": current_user["sub"]},
            {"$set": update_data}
        )
        
        # 记录审计日志
        await db.audit_logs.insert_one({
            "user_id": current_user["sub"],
            "action": "update_model_template",
            "resource_id": template_id,
            "resource_type": "model_template",
            "details": {"changes": list(update_data.keys())},
            "timestamp": datetime.utcnow()
        })
        
        # 获取更新后的模板
        updated = await db.model_templates.find_one({"id": template_id})
        return ModelTemplate(**updated)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新模板 {template_id} 失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新模板失败"
        )


@router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_template(
    template_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> None:
    """
    删除模型模板。
    
    Args:
        template_id: 模板ID
    """
    try:
        # 检查是否为官方模板
        for template in OFFICIAL_TEMPLATES:
            if template.id == template_id:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail="不能删除官方模板"
                )
        
        # 删除用户模板
        result = await db.model_templates.delete_one({
            "id": template_id,
            "created_by": current_user["sub"]
        })
        
        if result.deleted_count == 0:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="模板未找到"
            )
        
        # 记录审计日志
        await db.audit_logs.insert_one({
            "user_id": current_user["sub"],
            "action": "delete_model_template",
            "resource_id": template_id,
            "resource_type": "model_template",
            "timestamp": datetime.utcnow()
        })
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除模板 {template_id} 失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="删除模板失败"
        )


@router.get("/provider/{provider}", response_model=List[ModelTemplate])
async def get_templates_by_provider(
    provider: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> List[ModelTemplate]:
    """
    获取特定提供商的所有模板。
    
    Args:
        provider: 提供商名称
    
    Returns:
        模板列表
    """
    try:
        templates = []
        
        # 官方模板
        for template in OFFICIAL_TEMPLATES:
            if template.provider == provider:
                templates.append(template)
        
        # 用户模板
        user_templates = await db.model_templates.find({
            "provider": provider,
            "created_by": current_user["sub"]
        }).to_list(None)
        
        for tmpl in user_templates:
            templates.append(ModelTemplate(**tmpl))
        
        return templates
        
    except Exception as e:
        logger.error(f"获取提供商 {provider} 的模板失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取模板失败"
        )


@router.post("/{template_id}/use", response_model=Dict[str, Any])
async def use_template(
    template_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Dict[str, Any]:
    """
    使用模板（增加使用计数）。
    
    Args:
        template_id: 模板ID
    
    Returns:
        使用确认
    """
    try:
        # 更新使用计数
        await db.model_templates.update_one(
            {"id": template_id},
            {"$inc": {"usage_count": 1}}
        )
        
        # 记录使用历史
        await db.template_usage.insert_one({
            "template_id": template_id,
            "user_id": current_user["sub"],
            "timestamp": datetime.utcnow()
        })
        
        return {
            "success": True,
            "message": "模板使用记录已更新"
        }
        
    except Exception as e:
        logger.error(f"记录模板使用失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="记录模板使用失败"
        )